package versionx

import (
	"gitee.com/zhongguo168a/gocodes/datax"
	"gitee.com/zhongguo168a/gocodes/datax/mapx"
	"sync"
)

func NewSource() *Source {
	return &Source{
		enableVersion: false,
		origin:        datax.M{},
		versions:      map[string]int{},
	}
}

func NewSourceWith(origin datax.M) *Source {
	return &Source{
		enableVersion: false,
		origin:        origin,
		versions:      map[string]int{},
	}
}

type Source struct {
	// 数据
	origin datax.M
	// 版本信息
	versions map[string]int
	// 最后的版本号
	lastVersion int
	// 开启版本记录
	enableVersion bool
	//
	removed bool
	//
	onChange func(path, field string, val interface{})
	//
	mutex sync.RWMutex
}

func (s *Source) RefReset(val map[string]interface{}) {
	s.origin = val
	s.versions = map[string]int{}
	s.lastVersion = 0
	s.removed = false
}

func (s *Source) WithVersion() *Source {
	s.enableVersion = true
	s.versions = map[string]int{}
	return s
}

func (s *Source) RefIsRemove() bool {
	return s.removed
}

func (s *Source) Clone() (r *Source) {
	r = &Source{}
	s.mutex.Lock()
	r.origin = mapx.CloneMap(s.origin)
	s.mutex.Unlock()
	if s.enableVersion {
		r.versions = map[string]int{}
		for key, val := range s.versions {
			r.versions[key] = val
		}
		r.lastVersion = s.lastVersion
	}

	return
}

func (s *Source) Dispose() {
	s.origin = nil
	s.versions = nil
}

func (s *Source) RefRemove() {
	s.removed = true
}

// 实例最后更新的版本号
func (s *Source) RefLastVersion() int {
	return s.lastVersion
}

// 实例的版本信息
func (s *Source) RefVersions() (r map[string]int) {
	r = s.versions
	return
}

// 版本更新完成
func (s *Source) RefVersionComplete() {
	s.lastVersion++
}

// 重置版本号, 所有字段都发生变化
func (s *Source) KeyVersionReset() {
	s.lastVersion = -1
}

// 增加字段的版本
func (s *Source) KeyVersionNew(parents []string, path string) {
	s.mutex.Lock()
	s.keyVersionNew(parents, path)
	s.mutex.Unlock()
}

func (s *Source) keyVersionNew(parents []string, path string) {
	for _, val := range parents {
		s.versions[val] = s.lastVersion + 1
	}
	s.versions[path] = s.lastVersion + 1
}
